# !/usr/bin/env python
# -*- coding:utf-8 -*-
'''主界面

历史:
    2018-11-30 姚彧 创建
'''

__all__ = ['yMainWindow']


import os
import sys
from PyQt5.QtWidgets import QMainWindow, QTextEdit, QDesktopWidget, QMessageBox, QFileDialog, QInputDialog, QLineEdit
from PyQt5.QtGui import QIcon
from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt
from events.EventCenter import (EventDispatcher, EventContext)
from events.EventNames import EventNames
from tool.Singleton import Singleton
from tool.Delaunator import delaunay_triangulation_2_from_data_file
from project.manager import (ProjectManager, Project)
from app.user_config import UserConfig
from .ySimple3dWidget import ySimple3dWidget

def explorer_file(filename):
    '''打开文件(目录)'''
    if os.path.isfile(filename) or os.path.isdir(filename):
        os.startfile(filename)
    else:
        print('[%s]不存在!' % filename)

class yMainWindow(QtWidgets.QMainWindow, Singleton):
    def __init__(self):
        super().__init__()
        self.__init_environ()
        self.__init_ui()

    def emit(self, *args, **kwargs):
        return EventDispatcher().emit(*args, **kwargs)

    def __init_environ(self):
        self.__work_dir = UserConfig().lastest_project
        context = EventContext()
        self.emit('App.Environ.GetAll', context)
        self.__enriron = context['value']

    def __add_menugroup(self, name, items):
        parentMenu = self.menuBar().addMenu(name)
        for subitem in items:
            if len(subitem) > 1:
                action = parentMenu.addAction(subitem[0])
                action.triggered.connect(subitem[1])
            else:
                parentMenu.addSeparator()
        return parentMenu

    def __init_menu(self):
        # 菜单栏
        menu_groups = (('文件(&F)',[('新建项目...(&N)', self.project_create),
                                    ('打开项目...(&O)', self.project_open),
                                    ('关闭项目(&C)', self.project_close),
                                    '',
                                    ('打开项目工作目录(&W)', self.on_project_explorer_dir),
                                    '',
                                    ('退出(&X)', self.close)]),
                        ('数据管理(&D)', [('导入点文件...', self.on_data_import_points_file),
                                         ('打开点文件(&O)', self.on_data_open_file)]),
                        ('构网(&D)', [('构网', self.on_build_delaunay),]),
                        ('帮助(&H)', [('关于(&A)...', self.on_about),
                                        ('关于QT', self.on_aboutqt)]),
                                        
                        )
        self.__menus = {}
        for name, items in menu_groups:
            self.__menus[name] = self.__add_menugroup(name, items)
        self.menu_design = self.__menus[menu_groups[1][0]]
        self.menu_build = self.__menus[menu_groups[2][0]]

        self.__update_menus(False)

        # 状态栏
        self.statusBar().showMessage('程序已就绪...')

    def __update_menus(self, is_project_opened):
        self.menu_design.setEnabled(is_project_opened)
        self.menu_build.setEnabled(is_project_opened)
        self.setWindowTitle(self.__get_title())

    def project_create(self):
        print('新建项目...')
        project_dir = QFileDialog.getExistingDirectory(self,
                                                       "新建项目",
                                                       "")
        if os.path.isdir(project_dir):
            UserConfig().lastest_project = project_dir
            aproject = Project(project_dir)
            self.emit(EventNames.Project_Created, EventContext(project = aproject))
            self.__update_menus(True)

    def project_open(self):
        print('打开项目...')
        project_dir = QFileDialog.getExistingDirectory(self,
                                                       "打开项目",
                                                       self.__get_prev_dir())
        if os.path.isdir(project_dir):
            UserConfig().lastest_project = project_dir
            aproject = Project(project_dir)
            self.emit(EventNames.Project_Opened, EventContext(project = aproject))
            self.__update_menus(True)

    def on_project_explorer_dir(self):
        aproject = ProjectManager().project
        if aproject:
            assert isinstance(aproject, Project)
            explorer_file(aproject.project_dir)

    def project_close(self):
        print('关闭项目')
        self.emit(EventNames.Project_Close, EventContext())
        self.__update_menus(False)

    def __get_prev_dir(self):
        aproject = ProjectManager().project
        if isinstance(aproject, Project):
            return aproject.project_dir
        else:
            return self.__work_dir

    def on_about(self):
        box = QMessageBox(QMessageBox.Information, '关于{app_name}'.format(**self.__enriron), '作者: {author}\n版本: {version}\n日期: {version_date}      '.format(**self.__enriron))
        box.addButton(self.tr("确定"), QMessageBox.YesRole)
        box.setWindowIcon(self.app_icon)
        box.exec_()

    def on_aboutqt(self):
        QMessageBox.aboutQt(self)

    def on_data_import_points_file(self):
        title = '导入点文件'
        print('%s...' % title)
        fileName, filetype = QFileDialog.getOpenFileName(self,
                                                         title,
                                                         self.__get_prev_dir(),
                                                         "离散点文件 (*.txt)")
        if os.path.isfile(fileName):
            project = ProjectManager().project
            assert isinstance(project, Project)
            project.set_file('离散点文件', fileName)

    def on_data_open_file(self):
        project = ProjectManager().project
        assert isinstance(project, Project)
        if project:
            explorer_file(project.get_file('离散点文件'))

    def on_build_delaunay(self):
        print('构建Delaunay三角网')
        project = ProjectManager().project
        assert isinstance(project, Project)
        if project:
            data_file = project.get_file('离散点文件')
            res = delaunay_triangulation_2_from_data_file(data_file)
            self.vtk_simple.add_component({'data': res})

    def __get_title(self):
        project = ProjectManager().project
        if project is None:
            return self.title_prefix
        return '%s - [%s]' % (self.title_prefix, project.project_name)

    def __init_ui(self):
        self.app_icon = QIcon(':/icons/app.ico')
        self.title_prefix = '{app_name}'.format(**self.__enriron)
        self.setWindowTitle(self.__get_title())

        self.__init_menu()
        self.vtk_container = QtWidgets.QWidget(self)
        self.setCentralWidget(self.vtk_container)
        self.vtk_simple = ySimple3dWidget(self.vtk_container)
        self.setWindowIcon(self.app_icon)

        self.setGeometry(0, 0, 1024, 768)
        self.__center()
        self.show()
        self.vtk_simple.iren.Initialize()

    def __center(self):
        screen = QDesktopWidget().screenGeometry()
        size = self.geometry()
        self.move((screen.width()-size.width())/2, (screen.height()-size.height())/2)

    def on_event_add_dock(self, context:EventContext, *args, **kwargs):
        assert context.path == EventNames.UI_Dock_Add
        pane_args = context.get('pane_args')
        self.addDockWidget(*pane_args)

    @classmethod
    def register_events(cls):
        self = cls.getInstance()
        EventDispatcher().register(EventNames.UI_Dock_Add, self.on_event_add_dock)
